package com.dd.ms.common.util.json;

import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.JavaType;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.text.SimpleDateFormat;
import java.util.Collections;
import java.util.List;
import java.util.Map;

/**
 * @Author liuxianmeng
 * @CreateTime 2025/6/28 14:15
 * @Description JSON工具类（线程安全）
 *              功能：
 *              1. 对象↔JSON字符串互转
 *              2. 支持泛型对象转换（List/Map/自定义泛型）
 *              3. 日期格式化（默认ISO8601，可自定义）
 *              4. 空值处理（默认忽略null）
 *              5. 美化输出（格式化JSON）
 *              6. 未知属性忽略（防解析失败）
 *              7. 异常统一处理
 */
public class JsonUtils {

    private static final Logger log = LoggerFactory.getLogger(JsonUtils.class);
    private static final ObjectMapper mapper = new ObjectMapper();

    static {
        // 基础配置
        mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); // 忽略null字段
        mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); // 忽略未知属性
        mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); // 空对象不报错

        // Java8日期时间支持
        mapper.registerModule(new JavaTimeModule());
        mapper.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); // 使用ISO8601格式

        // 默认日期格式（可按需修改）
        mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
    }

    // ==================== 对象转JSON ====================

    /**
     * 对象转JSON字符串（自动处理日期格式）
     */
    public static String toJson(Object obj) {
        return toJson(obj, false);
    }

    /**
     * 对象转JSON字符串（带格式化选项）
     * @param obj 待转换对象
     * @param pretty 是否美化输出
     */
    public static String toJson(Object obj, boolean pretty) {
        try {
            if (pretty) {
                return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
            }
            return mapper.writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.error("对象转JSON失败: {}", e.getMessage(), e);
            throw new RuntimeException("JSON序列化失败", e);
        }
    }

    // ==================== JSON转对象 ====================

    /**
     * JSON字符串转对象（标准类型）
     * @param json  JSON字符串
     * @param clazz 目标类型
     */
    public static <T> T fromJson(String json, Class<T> clazz) {
        try {
            return mapper.readValue(json, clazz);
        } catch (JsonProcessingException e) {
            log.error("JSON解析失败: {} -> {}", json, e.getMessage(), e);
            throw new RuntimeException("JSON解析失败", e);
        }
    }

    /**
     * JSON字符串转List（支持泛型）
     * @param json  JSON字符串
     * @param clazz List元素类型
     * @return 非null List（解析失败返回空List）
     */
    public static <T> List<T> toList(String json, Class<T> clazz) {
        try {
            JavaType javaType = mapper.getTypeFactory().constructParametricType(List.class, clazz);
            return mapper.readValue(json, javaType);
        } catch (JsonProcessingException e) {
            log.error("JSON转List失败: {} -> {}", json, e.getMessage(), e);
            return Collections.emptyList();
        }
    }

    /**
     * JSON字符串转Map（支持复杂值类型）
     * @param json JSON字符串
     * @param keyClass   Key类型
     * @param valueClass Value类型
     */
    public static <K, V> Map<K, V> toMap(String json, Class<K> keyClass, Class<V> valueClass) {
        try {
            JavaType javaType = mapper.getTypeFactory().constructMapType(Map.class, keyClass, valueClass);
            return mapper.readValue(json, javaType);
        } catch (JsonProcessingException e) {
            log.error("JSON转Map失败: {} -> {}", json, e.getMessage(), e);
            return Collections.emptyMap();
        }
    }

    /**
     * JSON字符串转复杂泛型对象
     * 示例：TypeRef<ResponseDTO<List<User>>> type = new TypeRef<ResponseDTO<List<User>>>() {};
     */
    public static <T> T fromJson(String json, TypeReference<T> typeRef) {
        try {
            return mapper.readValue(json, typeRef);
        } catch (JsonProcessingException e) {
            log.error("JSON转复杂对象失败: {} -> {}", json, e.getMessage(), e);
            throw new RuntimeException("复杂JSON解析失败", e);
        }
    }

    // ==================== 高级功能 ====================

    /**
     * 深度拷贝对象（通过JSON序列化）
     * @param obj 原始对象
     * @return 新对象（失败返回null）
     */
    public static <T> T deepClone(T obj) {
        if (obj == null) return null;
        String json = toJson(obj);
        return fromJson(json, (Class<T>) obj.getClass());
    }

    /**
     * 格式化JSON字符串（美化输出）
     * @param json 原始JSON字符串
     * @return 格式化后的JSON（解析失败返回原始字符串）
     */
    public static String formatJson(String json) {
        try {
            Object obj = mapper.readValue(json, Object.class);
            return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
        } catch (JsonProcessingException e) {
            log.warn("JSON格式化失败，返回原始内容: {}", json);
            return json;
        }
    }

    /**
     * 动态修改日期格式（全局生效）
     * @param pattern 日期格式，如 "yyyy-MM-dd"
     */
    public static void setDateFormat(String pattern) {
        mapper.setDateFormat(new SimpleDateFormat(pattern));
    }
}
